from datetime import datetime
from typing import Any, Dict, List, Optional, Union

from pydantic import BaseModel, Field, validator


# 基础 Message Schema
class MessageBase(BaseModel):
    direction: str
    msg_type: str = "text"
    content: Optional[str] = None
    status: str = "sent"
    extra_data: Optional[Dict[str, Any]] = None


# 创建消息的 Schema
class MessageCreate(MessageBase):
    contact_id: Optional[int] = None
    session_id: int


# 更新消息的 Schema
class MessageUpdate(BaseModel):
    content: Optional[str] = None
    status: Optional[str] = None
    extra_data: Optional[Dict[str, Any]] = None
    pua_score: Optional[float] = None
    pua_patterns: Optional[List[Dict[str, Any]]] = None


# 数据库返回的 Message Schema
class MessageInDBBase(MessageBase):
    id: int
    contact_id: Optional[int]
    session_id: int
    sent_at: datetime
    pua_score: Optional[float] = None
    pua_patterns: Optional[List[Dict[str, Any]]] = None

    class Config:
        orm_mode = True

    @validator("pua_patterns", pre=True)
    def parse_pua_patterns(cls, v):
        """将JSON字符串转换为Python对象"""
        import json
        if isinstance(v, str):
            try:
                return json.loads(v)
            except json.JSONDecodeError:
                return None
        return v

    @validator("extra_data", pre=True)
    def parse_extra_data(cls, v):
        """将JSON字符串转换为Python对象"""
        import json
        if isinstance(v, str):
            try:
                return json.loads(v)
            except json.JSONDecodeError:
                return None
        return v


# 返回给API的 Message Schema
class Message(MessageInDBBase):
    pass


# 包含联系人信息的消息 Schema
class MessageWithContact(Message):
    contact_name: str = "Unknown"
    contact_relationship: Optional[str] = None


# 消息查询参数 Schema
class MessageQuery(BaseModel):
    contact_id: Optional[int] = None
    session_id: Optional[int] = None
    start_time: Optional[datetime] = None
    end_time: Optional[datetime] = None
    msg_type: Optional[str] = None
    direction: Optional[str] = None
    contains_text: Optional[str] = None
    has_pua: Optional[bool] = None
    min_pua_score: Optional[float] = None
    limit: int = 100
    offset: int = 0